package com.frank.feignDecoder.decoder;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.frank.feignDecoder.util.MyUtil;
import com.frank.globalException.domain.BaseResponse;
import com.frank.globalException.domain.EnumError;
import com.frank.globalException.exception.MyException;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;

/**
 * @author 小石潭记
 * @date 2020/10/22 10:15
 * @Description:
 * 我这边的需求是在decoder里面抛出异常，然后在advice里面处理，
 * 我这边抛出的自定义异常，结果在底层抛出的是decoderexpection，
 * 在advice手动处理一下该异常。
 */

@Component
public class MyDecoder implements Decoder {

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 这里统一处理，根据状态码判断返回正常还是异常的，
     * 200返回正常的，其他状态码直接抛出异常
     * 200返回decoder方法里面对应的type。201返回
     * List<T> result＝objectMapper.convertValue(data,new TypeReference<List>>() {}) ；
     * 这里的data是传入的从response取出的需要的值，然后转成具体业务需要的对象。
     */
    @Override
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
        if (response.status() >= 200 && response.status() <= 299) {
            String result = Util.toString(response.body().asReader());
            /*BaseResponse baseResponse = objectMapper.readValue(result, BaseResponse.class);
            int code = baseResponse.getCode();
            if (code == 200) {
                return baseResponse;
            }*/
            String code = "";
            Map<String, Object> resultMap = objectMapper.readValue(result, Map.class);
            if (resultMap.containsKey("code")) {
                code = String.valueOf(resultMap.get("code"));
            } else if (resultMap.containsKey("CODE")) {
                code = String.valueOf(resultMap.get("CODE"));
            }
            // 如果是200 则返回对应的对象
            if ("200".equals(code)) {
                JavaType javaType = MyUtil.getJavaType(type);
                return objectMapper.convertValue(resultMap, javaType);
            }
            return resultMap;
//            throw new MyException(EnumError.BAD_REQUEST);
        }
        throw new MyException(EnumError.OTHER_ERROR);
    }

}